import datetime
from datetime import timedelta
import json
import logging

from django.conf import settings
from django.db.models import F, Count
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django_redis import get_redis_connection
from django.db import connection

from web import models
from web.utils.blackip import BlackIp

logger = logging.getLogger(__name__)

# In your code

logger.debug('Some message')  # Logs as debug message
logger.error('Error message')  # Logs as error message


@csrf_exempt
def blockip_api(request):
    current_datetime = datetime.datetime.now()
    current_time = current_datetime.time()
    specific_time = datetime.time(hour=15, minute=00, second=0, microsecond=0)
    if current_time > specific_time:
        specific_datetime = current_datetime + timedelta(days=1)
    else:
        specific_datetime = current_datetime
    if request.method == 'POST':
        try:
            # 高危告警大于50次
            sql = """
                   select src_ip from web_botgateattackip where 
                   DATE_FORMAT(create_datetime,"%%Y-%%m-%%d") = %s 
                   and (high_risk_count+middle_risk_count+low_risk_count)>20   
                   """
            rows = execute_sql_with_params(sql, specific_datetime.strftime('%Y-%m-%d'))
            warningip_list = [row[0] for row in rows]

            # 漏洞攻击大于50次
            inject_attack_queryset = models.BotgateAttackIp.objects.filter(create_datetime__year=specific_datetime.year,
                                                                           create_datetime__month=specific_datetime.month,
                                                                           create_datetime__day=specific_datetime.day,
                                                                           inject_attack_count__gt=20)
            injectattackip_list = [item.src_ip for item in inject_attack_queryset]

            # nday攻击大于1次
            nday_attack_queryset = models.BotgateAttackIp.objects.filter(create_datetime__year=specific_datetime.year,
                                                                         create_datetime__month=specific_datetime.month,
                                                                         create_datetime__day=specific_datetime.day,
                                                                         nday_name_count__gte=3)
            ndayattackip_list = [item.src_ip for item in nday_attack_queryset]

            botgate_blockip_set = set(warningip_list + injectattackip_list + ndayattackip_list)

            # 关联告警IP
            sangfor_fw_attackip = models.SangforFwAttackLog.objects.filter(create_datetime__year=specific_datetime.year,
                                                                           create_datetime__month=specific_datetime.month,
                                                                           create_datetime__day=specific_datetime.day). \
                values('src_ip').annotate(ct=Count('src_ip'))
            sangfor_fw_attackip_list = [item['src_ip'] for item in sangfor_fw_attackip]

            skyeye_attackip = models.SkyEyeLog.objects.filter(create_datetime__year=specific_datetime.year,
                                                              create_datetime__month=specific_datetime.month,
                                                              create_datetime__day=specific_datetime.day). \
                values("attack_sip").annotate(ct=Count('attack_sip'))
            skyeye_attackip_list = [item['attack_sip'] for item in skyeye_attackip]

            # 把恶意IP做交集运算，查询出关联告警的IP，加入自动封禁列表
            sangfor_fw_relate_botgate = set(sangfor_fw_attackip_list).intersection(botgate_blockip_set)
            sangfor_fw_relate_skyeye = (set(sangfor_fw_attackip_list).intersection(skyeye_attackip_list))
            skyeye_relate_botgate = set(skyeye_attackip_list).intersection(botgate_blockip_set)
            skyeye_relate_sangfor_fw = set(skyeye_attackip_list).intersection(sangfor_fw_attackip_list)

            sangfor_fw_blockip_set = sangfor_fw_relate_botgate.union(sangfor_fw_relate_skyeye)
            skyeye_blockip_set = skyeye_relate_botgate.union(skyeye_relate_sangfor_fw)
            sangfor_fw_blockip_set = sangfor_fw_blockip_set.union(skyeye_blockip_set)

            # 查询IP是否已经被封禁,如果被封禁，则不再重复封禁
            botgate_blackip_list = []
            sangfor_fw_blackip_list = []
            for ip in botgate_blockip_set:
                is_exists = models.BlockIp.objects.filter(unblock_datetime__gt=current_datetime,
                                                          block_device='botgate',
                                                          src_ip=ip).exists()
                if not is_exists:
                    botgate_blackip_list.append(ip)
            for ip in sangfor_fw_blockip_set:
                is_exists = models.BlockIp.objects.filter(unblock_datetime__gt=current_datetime,
                                                          block_device='sangfor_fw',
                                                          src_ip=ip).exists()
                if not is_exists:
                    sangfor_fw_blackip_list.append(ip)
        except Exception as ex:
            print(ex)
            return JsonResponse({'success': False})
        conn = get_redis_connection('default')
        if len(botgate_blackip_list) > 0:
            for ip in botgate_blackip_list:
                obj = models.BotgateAttackIp.objects.filter(src_ip=ip).first()
                location = obj.location
                blackip_obj = BlackIp(ip, 'botgate', settings.AUTOMATIC_BLOCK, settings.BLOCK, 1, specific_datetime,
                                      location)
                conn.lpush(settings.QUEUE_TASK_NAME, str(blackip_obj))
        else:
            botgate_unblockip_queryset = models.BlockIp.objects.filter(unblock_datetime__lt=current_datetime,
                                                                       block_device='botgate',
                                                                       status=1)
            for ip in botgate_unblockip_queryset:
                obj = models.BotgateAttackIp.objects.filter(src_ip=ip.src_ip).first()
                location = obj.location
                blackip_obj = BlackIp(ip, 'botgate', settings.AUTOMATIC_BLOCK, settings.UNBLOCK, 0, specific_datetime,
                                      location)
                conn.lpush(settings.QUEUE_TASK_NAME, str(blackip_obj))
        for ip in sangfor_fw_blackip_list:
            botgate_obj = models.BotgateAttackIp.objects.filter(src_ip=ip).first()
            sangfor_fw_obj = models.SangforFwAttackLog.objects.filter(src_ip=ip).first()
            skyeye_obj = models.SkyEyeLog.objects.filter(attack_sip=ip).first()
            if botgate_obj:
                location = botgate_obj.location
            elif sangfor_fw_obj:
                location = sangfor_fw_obj.src_ip_addr
            else:
                location = skyeye_obj.location

            blackip_obj = BlackIp(ip, 'sangfor_fw', settings.AUTOMATIC_BLOCK, settings.BLOCK, 1, specific_datetime,
                                  location)
            conn.lpush(settings.QUEUE_TASK_NAME, str(blackip_obj))

        return JsonResponse({'success': True})


def execute_sql_with_params(sql, params):
    with connection.cursor() as cursor:
        cursor.execute(sql, params)
        rows = cursor.fetchall()
    return rows
